Redux中只會有一個store,還記得前面幾天我們說的 「Single source of truth」 嗎?Store就是每個state組成的state tree,用來管理專案中所有的state,上一篇我們用combineReducers()
把reducers組合在一起,包成一個大~reducer,再來我們要用createStore()
來產生完整的store。
一般來說,如果我們只有一個reducer,我們可以透過createStore()
來產生對應的一個state:
import { createStore } from 'redux';
import todo from './reducers/todo';
// store會是 { todo: [] }
let store = createStore(todo);
當我們透過前一天說的combineReducers()
組合多個reducer,就會是這樣指定給store:
import { createStore } from 'redux';
import todoApp from './reducers';
// store會是 { todo: [], filter: 'SHOW_ALL' }
let store = createStore(todoApp);
當store被建立的時候,Redux會先dispatch一個action,這會讓reducer先把預設的state設定到store中,所以當我們在寫reducer funtion的時候,記得要帶入預設值,否則該state一開始會是undefined。
Store儲存了一個state tree,但它不只是這樣,它還提供了一些方法可以使用:
以下先介紹一下這些方法。
它會傳回當下store儲存的state tree object,有時候在產生action時,會需要依據其他state來處理,這時候就可以用getState()來取得目前的state。例如要取得todo目前的值,可以呼叫getState().todo
。
透過dispatch發送一個action,這是Redux中唯一改變state的方式。
設定一個listener事件,state一旦發生變化,就會呼叫這個listener,在listener裡面可以用store.getState()來取得當前的state tree。 (不過,一般來說很少會用到這個方法,可以先參考看看就好。)
替換產生store的reducer,這是在已經建立store之後,如果要把原本的某個state對應到不同的reducer function。 (通常也是很少會用到,所以這邊列出來參考即可。)
有了這些store的概念後,我們在原本的todos範例中,加上createStore(todoApp)
產生store,再使用剛剛提到的兩個store方法,就可以從log看到actions、reducers與store之間的變化囉!
createStore(rootReducer)
建立store。store.getState()
看看目前的state tree,filter為SHOW_ALL,todos初始值為空陣列,跟我們在reducer function預設的一樣。store.subscribe
,每當state發生變化,再印出state tree目前狀態。store.dispatch(action)
,這邊新增task進去。完整index.js程式碼:
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import * as todoActions from './actions/todos';
import todoApp from './reducers';
import App from './app';
// 建立store
let store = createStore(todoApp);
// 初始store值
console.log(store.getState());
// 透過store.subscribe,偵聽store變化記錄log
let listener = store.subscribe(() =>
console.log(store.getState())
);
// 使用store.dispatch,發送action
store.dispatch(todoActions.addTask('Test'));
ReactDOM.render(
<App />,
document.getElementById('main')
);
可以參考這張圖,觀察log情形:
目前我們還沒有把Redux跟React做結合,但Redux的精神已經實作完成!下一階段就會說明把Redux和React結合的方式囉!今天的檔案已經放在Git上,可以執行 npm run dev 看到log的結果喔!(如果沒有的話,請再次執行npm install看看,因為這次有加上redux的package喔!)